Mutable objects are those whose state can be changed. For instance, an array is mutable, but a String is not. Private mutable class members should
never be returned to a caller or accepted and stored directly. Doing so leaves you vulnerable to unexpected changes in your class state.
Instead use an unmodifiable Collection
(via Collections.unmodifiableCollection
,
Collections.unmodifiableList
, …) or make a copy of the mutable object, and store or return the copy instead.
This rule checks that private arrays, collections and Dates are not stored or returned directly.
Exceptions
The rule violation is not reported for mutable values stored in private methods if no non-private methods directly passes a mutable parameter to
them.
Noncompliant code example
class A {
private String [] strings;
public A () {
strings = new String[]{"first", "second"};
}
public String [] getStrings() {
return strings; // Noncompliant
}
public void setStrings(String [] strings) {
this.strings = strings; // Noncompliant
}
}
public class B {
private A a = new A(); // At this point a.strings = {"first", "second"};
public void wreakHavoc() {
a.getStrings()[0] = "yellow"; // a.strings = {"yellow", "second"};
}
}
Compliant solution
class A {
private String [] strings;
public A () {
strings = new String[]{"first", "second"};
}
public String [] getStrings() {
return strings.clone();
}
private void setStringsInternal(String [] strings) {
this.strings = strings;
}
public void setStrings(String [] strings) {
this.strings = strings.clone();
}
}
public class B {
private A a = new A(); // At this point a.strings = {"first", "second"};
public void wreakHavoc() {
a.getStrings()[0] = "yellow"; // a.strings = {"first", "second"};
}
}